package com.yuand.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yuand.annotation.SysLog;
import com.yuand.config.Result;
import com.yuand.config.UserThreadLocal;
import com.yuand.core.RedisService;
import com.yuand.entity.SysUser;
import com.yuand.mapper.SysUserMapper;
import com.yuand.core.JwtService;
import com.yuand.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpSession;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;
import java.io.UnsupportedEncodingException;
import java.util.concurrent.TimeUnit;

/**
 * @author yuandong
 * @date 2021/9/4 9:43
 */
@Slf4j
@RestController
@RequestMapping("/user")
public class SysUserController {

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private JwtService jwtService;

    @Autowired
    private RedisService redisService;

    /**
     * 登录页面
     *
     * @param user
     * @return
     */
    @SysLog("用户登录")
    @PostMapping("/login")
    public Result<?> login(@RequestBody SysUser user, HttpSession session) {
        SysUser u = sysUserMapper.selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, user.getUsername()).eq(SysUser::getPassword, user.getPassword()));
        if (u == null) {
            return Result.error("-1", "用户名或密码错误");
        }
        String token = jwtService.createToken(u.getUsername());
        u.setToken(token);
        System.out.println("后台生成的token....." + token);
        //1:登录成功后，前台需要将后台查到的用户信息缓存起来，这里将user对象返给前台
        //sessionStorage.setItem("user",JSON.stringify(res.data));  //登录成功后，前台将用户缓存起来  这段代码是前端写的
        //2:后台将token保存到redis中  有效期这里设置的是1天  生成token的时候已经加了过期时间，验证token的时候也加了是否过期，这里不用在redis里面保存token,只保存用户信息即可
        //redisService.set("TOKEN_"+token, JSON.toJSONString(u),1, TimeUnit.DAYS);
        session.setAttribute("currentUser",(SysUser)u);
        redisService.set("sys_user"+u.getId().toString(), u);
        return Result.success(u);
    }


    @SysLog("用户详情")
    @GetMapping("/info")
    public Result userinfo(String token) {
        String username = jwtService.getUsername(token);
        SysUser sysUser = sysUserMapper.selectOne(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, username));
        return Result.success(sysUser);
    }


    /**
     * 新增用户
     *
     * @return
     * @RequestBody 前台传递的json 转换成user对象
     */
    @PostMapping("/save")
    public Result<?> save(@RequestBody SysUser user) {
        if (user.getPassword() == null || user.getPassword().equals("")) {
            user.setPassword("123");
        }
        sysUserMapper.insert(user);
        return Result.success();
    }


    /**
     * 修改用户
     *
     * @param user
     * @return
     */
    @PutMapping("/update")
    public Result<?> update(@RequestBody SysUser user) {
        sysUserMapper.updateById(user);
        return Result.success();
    }


    /**
     * 删除用户
     *
     * @param id
     * @return
     */
    @DeleteMapping("/del/{id}")
    public Result<?> del(@PathVariable int id) {
        sysUserMapper.deleteById(id);
        return Result.success();
    }


    /**
     * 分页查询
     * 如果前端没有传递参数，可以在这里使用defaultValue设置默认值
     *
     * @param pageNum
     * @param pageSize
     * @param sysUser
     * @return
     */
    @GetMapping("/selectList")
    public Result<?> selectList(@RequestParam(defaultValue = "1") Integer pageNum,
                                @RequestParam(defaultValue = "10") Integer pageSize,
                               SysUser sysUser) {
        Page<SysUser> page = new Page<>(pageNum, pageSize);
        //构造器
        QueryWrapper queryWrapper = new QueryWrapper();
        if (StringUtils.isNotNull(sysUser.getNickName())) {
            queryWrapper.like("nick_name", sysUser.getNickName());
        }
        if (StringUtils.isNotNull(sysUser.getUsername())) {
            queryWrapper.like("username", sysUser.getUsername());
        }

        Page<SysUser> userPage = sysUserMapper.selectPage(page, queryWrapper);
        return Result.success(userPage);
    }

    /**
     * 推出登录
     *
     * @param session
     * @return
     */
    @GetMapping("/logout")
    public Result logout(HttpSession session) {
        //redisService.del("sys_user");
        session.removeAttribute("user");
        return Result.success("退出成功");
    }


    /**
     * 用户修改密码
     *
     * @return
     * @Size(max = 16, message = "新密码长度不能超过16个字符")
     */
    @PostMapping("/updatePassWord")
    @Validated
    public Result updatePassWord(@RequestBody SysUser user) {
        //首先判断是否是超管
        SysUser sysUser = (SysUser) redisService.get("sys_user"+user.getId());
        if (sysUser.isAdmin()) {
            return Result.error("-1", "不允许操作超级管理员用户");
        }
        //实际操作时此处需要对密码加密
        sysUser.setPassword(user.getPassword());
        this.sysUserMapper.updateById(sysUser);
        return Result.success("修改成功");
    }


    /**
     * 未登录，没有token会重定向到这个方法来
     *
     * @param msg
     * @return
     * @throws UnsupportedEncodingException
     */
    @GetMapping("/unlogin")
    public Result unlogin(String msg) throws UnsupportedEncodingException {

        return Result.error("-1", "请重新登录");
    }

}
